package com.logic.comment.util;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import javax.validation.constraints.NotNull;
import java.lang.reflect.Field;
import java.util.Objects;

@Slf4j
public class BeanUtil {

    public static Selector selector() {
        return new Selector();
    }

    @Data
    @NotNull
    public static class Selector {
        private boolean isTrue = true;

        public Selector eq(Object select, Object po) {
            if (!isTrue) {
                return this;
            }
            isTrue = select == null || Objects.equals(select, po);
            return this;
        }

        public Selector bool(boolean b) {
            isTrue = b;
            return this;
        }

        public Selector contains(Object select, Object po) {
            isTrue = select == null || po.toString().contains(select.toString());
            return this;
        }

        public boolean value() {
            return isTrue;
        }
    }

    /**
     * 获取指定字段的注释
     */
    public static String getTargetInfo(Object object, String fieldName) {
        Class<?> clazz = object.getClass();
        try {
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true); // 设置私有字段可访问
                String updateFieldName = field.getName();

                if (updateFieldName.equals(fieldName)) {
                    String back = null;
                    ApiModelProperty annotation = field.getAnnotation(ApiModelProperty.class);
                    if (annotation != null) {
                        back = annotation.value();
                    } else {
                        back = field.getName();
                    }
                    return back;
                }
            }
        } catch (SecurityException e) {
            throw new RuntimeException(e);
        }
        return "";
    }

    /**
     * 获取对象指定字段的double值
     */
    public static Double getTargetValue(Object object, String fieldName) {
        Class<?> clazz = object.getClass();
        try {
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true); // 设置私有字段可访问
                String updateFieldName = field.getName();

                if (updateFieldName.equals(fieldName)) {
                    String string = field.get(object).toString();
                    if (!string.contains(".")) {
                        string += ".0";
                    }
                    return Double.valueOf(string);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return 0.0;
    }

    /**
     * 更新字段的 数值 增量更新
     *
     * @param waitingUpdate   更新对象
     * @param name            字段名
     * @param thisChangeValue 增量更新值
     * @return
     */
    public static <T> Object updateField(
            T waitingUpdate, String name, Object thisChangeValue
    ) {
        Class<?> clazz = waitingUpdate.getClass();
        try {
            Field field = clazz.getDeclaredField(name);

            field.setAccessible(true); // 设置私有字段可访问

            String updateFieldName = field.getName();

            if (!updateFieldName.isEmpty()) {
                double changeValue = Double.parseDouble(thisChangeValue.toString());
                Class<?> type = field.getType();
                if (type.equals(Long.class)) {
                    long sourceValue = Long.parseLong(field.get(waitingUpdate).toString());
                    long targetValue = (long) (sourceValue + changeValue);
                    if (targetValue < 0) {
                        targetValue = 0L;
                        thisChangeValue = targetValue - sourceValue;
                    }
                    log.info("更新字段(long):{}:{}--->{}({})", name, sourceValue, thisChangeValue, targetValue);
                    field.set(waitingUpdate, targetValue);
                    return targetValue;
                }
                if (type.equals(Double.class)) {
                    double sourceValue = Double.parseDouble(field.get(waitingUpdate).toString());
                    double targetValue = sourceValue + changeValue;
                    if (targetValue < 0) {
                        targetValue = 0.0;
                        thisChangeValue = targetValue - sourceValue;
                    }
                    log.info("更新字段(double):{}:{}--->{}({})", name, sourceValue, thisChangeValue, targetValue);
                    field.set(waitingUpdate, targetValue);
                    return targetValue;
                }
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            log.error("增量更新字段失败:{}", e.getMessage());
        }
        return 0;
    }
}
